#ifndef __FW_FONT_H__
#define __FW_FONT_H__



namespace freewrite
{

struct Character
{
	Font* m_Font;
	FontMap* m_FontMap;
	Character* m_Next;
	char32_t m_Char;
	uint32_t m_RefCount;
	int16_t m_Size;
	int16_t m_BmpWidth;
	int16_t m_BmpHeight;
	int16_t m_DrawOffsetX;
	int16_t m_DrawOffsetY;
	int16_t m_AdvanceX;
	int16_t m_AdvanceY;
	int16_t m_Index;
	int16_t m_MipLevel;

	Character(Font* pFont, uint32_t chr, int16_t size,
		int16_t bmpWidth, int16_t bmpHeight,
		int16_t vDrawOffsetX, int16_t vDrawOffsetY,
		int16_t vAdvanceX, int16_t vAdvanceY)
		: m_Font(pFont)
		, m_FontMap(nullptr)
		, m_Char(chr)
		, m_Size(size)
		, m_BmpWidth(bmpWidth)
		, m_BmpHeight(bmpHeight)
		, m_Index(-1)
		, m_MipLevel(-1)
		, m_RefCount(0)
		, m_Next(nullptr)
		, m_DrawOffsetX(vDrawOffsetX)
		, m_DrawOffsetY(vDrawOffsetY)
		, m_AdvanceX(vAdvanceX)
		, m_AdvanceY(vAdvanceY)
	{
	}

	Vector2I16 GetKerning(const Character* pPrev) const;

	IFWTexture2D* GetTexture() const;
	
	Vector4U16 GetSubUVNormalized() const;
	
	inline bool IsWhiteSpace() const
	{
		return m_Char == ' ' || m_BmpWidth == 0 || m_BmpHeight == 0; 
	}
};

class Font
{
	FW_NO_COPYCONSTRUCT(Font);

	FontCache* m_Parent;
	FontFaceImpl* m_Face;
	std::vector<Character*> m_CharTable;

	friend class FontCache;
	friend struct Character;

private:
	Font(FontFaceImpl* m_Face, FontCache* parent);
	void InsertCharacter(Character* chr);

public:
	~Font();
	Character* GetCharacter(char32_t chr, int16_t size, bool bDoNotWait);
	Character* FindCharacter(char32_t chr, int16_t size);
	uint32_t MesureString();
};


}

#endif//__FW_FONT_H__